// 防止头文件被多次包含的宏定义
// 这是C/C++中标准的头文件保护机制，确保头文件内容只被编译一次
#ifndef STORAGE_ENGINE_H
#define STORAGE_ENGINE_H

// 包含必要的标准库头文件
#include <string>    // 用于字符串处理
#include <memory>    // 用于智能指针（std::shared_ptr, std::unique_ptr）
#include "page.h"    // 包含页结构定义，page_id_t 和 Page 类在这里定义
#include"common.h"
// #include"simple_wal.h" //新增：包含极简WAL日志管理器定义

//后台线程相关
#include <thread>       // 线程
#include <mutex>        // 互斥锁
#include <condition_variable> // 条件变量
#include <atomic>       // 原子变量（线程安全的标志位）

/**
 * @brief 存储引擎统计信息结构体
 * 用于记录和监控存储引擎的性能指标
 */
struct CacheStats {
    size_t total_requests = 0;      // 总请求次数，所有读/写请求的计数
    size_t cache_hits = 0;          // 缓存命中次数，请求的页已在缓存中的次数
    size_t cache_misses = 0;        // 缓存未命中次数，请求的页不在缓存中需要从磁盘读取的次数
    size_t disk_reads = 0;          // 磁盘读取次数，实际从磁盘读取页的次数
    size_t disk_writes = 0;         // 磁盘写入次数，实际向磁盘写入页的次数
    size_t page_replacements = 0;   // 页替换次数，缓存满时替换页的次数

    /**
     * @brief 计算缓存命中率
     * @return 命中率，范围0.0到1.0
     */
    double hit_ratio() const {
        return total_requests > 0 ? static_cast<double>(cache_hits) / total_requests : 0.0;
    }
};

/**
 * @brief 存储引擎主类，提供统一的存储访问接口
 * 这是整个存储系统的门面类，对外提供简洁的API
 */
class StorageEngine {
public:
    /**
     * @brief 构造函数
     * @param db_name 数据库名称，用于创建数据文件（如："./data/mydatabase"）
     * @param buffer_pool_size 缓存池大小（页数），默认1024页（如4KB/页则为4MB缓存）
     */
    StorageEngine(const std::string& db_name, size_t buffer_pool_size = 1024);
    
    /**
     * @brief 析构函数，确保所有脏页写回磁盘
     * RAII原则：在对象销毁时自动清理资源，防止数据丢失
     */
    ~StorageEngine();

    // 禁用拷贝构造函数和拷贝赋值运算符
    // StorageEngine 管理重要资源，不应被随意拷贝
    StorageEngine(const StorageEngine&) = delete;
    StorageEngine& operator=(const StorageEngine&) = delete;
    
    // 禁用移动构造函数和移动赋值运算符
    // 确保资源的唯一所有权，避免悬空指针
    StorageEngine(StorageEngine&&) = delete;
    StorageEngine& operator=(StorageEngine&&) = delete;

    /**
     * @brief 分配一个新页
     * @return 新分配的页ID，如果失败返回INVALID_PAGE_ID（通常定义为-1）
     * 在磁盘上分配空间，并返回唯一的页标识符
     */
    page_id_t allocate_page();

    /**
     * @brief 释放一个页
     * @param page_id 要释放的页ID
     * @return 是否成功
     * 释放页占用的磁盘空间，并从缓存中移除（如果存在）
     */
    bool free_page(page_id_t page_id);

    /**
     * @brief 读取一个页到内存（优先从缓存中获取）
     * @param page_id 要读取的页ID
     * @return 页的智能指针，如果失败返回nullptr
     * 核心读操作：先查缓存，缓存未命中则从磁盘读取并加入缓存
     */
    std::shared_ptr<Page> read_page(page_id_t page_id);

    /**
     * @brief 写入一个页（标记为脏页，延迟写回）
     * @param page 要写入的页（通过智能指针传递，确保页对象不会被意外释放）
     * @return 是否成功
     * 延迟写策略：只标记页为脏页，实际写磁盘操作延迟到必要时进行
     */
    // bool write_page(const std::shared_ptr<Page>& page,uint32_t offset,const std::string& data);
    bool write_page(const std::shared_ptr<Page>& page);

    /**
     * @brief 获取页（优先从缓存中获取，等同于read_page）
     * @param page_id 页ID
     * @return 页的智能指针
     * 提供更直观的接口名称，功能与read_page相同
     */
    std::shared_ptr<Page> get_page(page_id_t page_id);

    /**
     * @brief 立即将脏页写回磁盘
     * @param page_id 页ID
     * @return 是否成功
     * 强制写回：用于确保数据持久化，如事务提交时
     */
    bool flush_page(page_id_t page_id);

    /**
     * @brief 将所有脏页写回磁盘
     * 用于系统关闭前或检查点时确保所有修改持久化到磁盘
     */
    void flush_all_pages();

    /**
     * @brief 获取缓存统计信息
     * @return 缓存统计信息结构体
     * 用于性能监控和系统调优
     */
    CacheStats cache_stats() const;

    /**
     * @brief 重置缓存统计信息
     * 用于重新开始性能统计，如测试不同工作负载时
     */
    void reset_stats();

    /**
     * @brief 设置替换策略（LRU或FIFO）
     * @param use_lru 是否使用LRU策略，true为LRU，false为FIFO
     * 策略模式：允许运行时动态切换缓存替换算法
     */
    void set_replacement_policy(bool use_lru);

    /**
     * @brief 获取当前数据库使用的页数量
     * @return 已分配的页数量
     * 用于监控数据库大小和空间使用情况
     */
    size_t get_page_count() const;

    /**
     * @brief 获取缓存池大小
     * @return 缓存池容量（页数）
     * 用于了解系统配置和性能调优
     */
    size_t get_buffer_pool_size() const;

private:
    // Pimpl（Pointer to Implementation）惯用法
    // 前向声明实现类，将实现细节完全隐藏在.cpp文件中
    class Impl;
    
    // 使用unique_ptr管理实现对象，确保资源的唯一所有权
    // 这种设计减少了编译依赖，提高了接口的稳定性
    std::unique_ptr<Impl> impl_;
    
};

// 结束头文件保护
#endif // STORAGE_ENGINE_H